package com.xyw.code.platform.webapps.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyw.code.common.core.constant.IsDelEnum;
import com.xyw.code.common.core.exception.BaseException;
import com.xyw.code.platform.common.entity.dto.MenuDTO;
import com.xyw.code.platform.common.entity.enums.CommonStatusEnum;
import com.xyw.code.platform.common.entity.enums.MenuConstant;
import com.xyw.code.platform.common.entity.enums.PlatformErrorType;
import com.xyw.code.platform.common.entity.po.SysMenu;
import com.xyw.code.platform.common.entity.po.SysUser;
import com.xyw.code.platform.common.entity.util.XUtil;
import com.xyw.code.platform.webapps.dao.SysMenuMapper;
import com.xyw.code.platform.webapps.dao.SysUserMapper;
import com.xyw.code.platform.webapps.service.ISysMenuService;
import com.xyw.code.platform.webapps.service.ISysRoleMenuService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 菜单权限表 服务实现类
 * </p>
 *
 * @author xyw
 * @since 2020-02-07
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private ISysRoleMenuService roleMenuService;

    @Override
    public List<SysMenu> userResource(String username) {
        List<SysMenu> menus = sysMenuMapper.userResource(username);
        return menus;
    }

    @Override
    public List<SysMenu> selectMenuTree(Long userId) {
        List<SysMenu> menus = getMenuList(null,userId,null);
        List<SysMenu> outMenus = new ArrayList<>();
        menus.forEach(menu->{
            if(menu.getParentId()==null || 0==menu.getParentId()){
                menu.setLevel(0);
                if(!XUtil.exists(outMenus,menu)){
                    outMenus.add(menu);
                }
            }
        });
        outMenus.sort(((o1, o2) -> o1.getSort().compareTo(o2.getSort())));
        XUtil.findMenuChild(outMenus,menus,0);
        return outMenus;
    }

    private List<SysMenu> getMenuList(String name,Long userId,Long menuId){
        LambdaQueryWrapper<SysMenu> sysMenuLambdaQueryWrapper = Wrappers.<SysMenu>query().lambda();
        sysMenuLambdaQueryWrapper.select(SysMenu::getId, SysMenu::getName, SysMenu::getPerms, SysMenu::getPath, SysMenu::getParentId, SysMenu::getComponent, SysMenu::getIsFrame, SysMenu::getIcon, SysMenu::getSort, SysMenu::getType, SysMenu::getDelFlag);
        if(menuId!=null){
            sysMenuLambdaQueryWrapper.eq(SysMenu::getId,menuId);
        }
        if(userId!=null){
            List<String> menuIds = roleMenuService.getMenuIdByUserId(userId);
            if(menuIds.size()>0){
                sysMenuLambdaQueryWrapper.in(SysMenu::getId,menuIds);
            }
        }
        if(StringUtils.isNotBlank(name)){
            sysMenuLambdaQueryWrapper.like(SysMenu::getName,name);
        }
        sysMenuLambdaQueryWrapper.eq(SysMenu::getDelFlag,Boolean.FALSE);
        List<SysMenu> menus = baseMapper.selectList(sysMenuLambdaQueryWrapper);
        return menus;
    }


    @Override
    public List<SysMenu> getMenuTreeList(String name) {
        List<SysMenu> menus = getMenuList(name,null,null);
        List<SysMenu> outMenus = new ArrayList<>();
        menus.forEach(menu->{
            if( menu.getParentId() == null||  0==menu.getParentId()){
                menu.setLevel(0);
                if(!XUtil.exists(outMenus,menu)){
                    outMenus.add(menu);
                }
            }
        });
        outMenus.sort(((o1, o2) -> o1.getSort().compareTo(o2.getSort())));
        XUtil.findMenuChild(outMenus,menus,0);
        return outMenus;
    }



    @Override
    public boolean updateMenuById(MenuDTO menuDto) {
        SysMenu sysMenu = new SysMenu();
        BeanUtils.copyProperties(menuDto, sysMenu);
        // 菜单校验
        verifyForm(sysMenu);
        return this.updateById(sysMenu);
    }

    @Override
    public SysMenu getMenuById(Long parentId) {
        return baseMapper.selectOne(Wrappers.<SysMenu>lambdaQuery().select(SysMenu::getType).eq(SysMenu::getId, parentId));
    }

    @Override
    public boolean deleteMenu(Long menuId) {
        List<SysMenu> menus = getMenuList(null,null,menuId);
        List<SysMenu> allMenus = getMenuList(null,null,null);
        XUtil.findMenuChild(menus,allMenus,0);
        List<Long> ids = XUtil.findChildrenIds(new ArrayList<Long>(),menus.get(0));
        ids.add(menus.get(0).getId());
        List<SysMenu> delMenu = new ArrayList<>();
        ids.forEach(id->{
            SysMenu sysMenu = new SysMenu();
            sysMenu.setId(id);
            sysMenu.setDelFlag(CommonStatusEnum.DELETE.getType());
            delMenu.add(sysMenu);
        });
        return  updateBatchById(delMenu);
    }


    /**
     * 验证菜单参数是否正确
     */
    private void verifyForm(SysMenu menu) {
        //上级菜单类型
        int parentType = MenuConstant.MenuType.CATALOG.getValue();
        if (0!=menu.getParentId()) {
            SysMenu parentMenu = getMenuById(menu.getParentId());
            parentType = parentMenu.getType();
        }
        //目录、菜单
        if (menu.getType() == MenuConstant.MenuType.CATALOG.getValue() ||
                menu.getType() == MenuConstant.MenuType.MENU.getValue()) {
            if (parentType != MenuConstant.MenuType.CATALOG.getValue()) {
                throw new BaseException(PlatformErrorType.PARENT_IS_ONLY_CATALOG);
            }
            return;
        }
        //按钮
        if (menu.getType() == MenuConstant.MenuType.BUTTON.getValue()) {
            if (parentType != MenuConstant.MenuType.MENU.getValue()) {
                throw new BaseException(PlatformErrorType.PARENT_IS_ONLY_MENU);
            }
        }
    }
}
